package com.gw.vip.server.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gw.vip.common.enums.StatusEnums;
import com.gw.vip.common.exception.ExceptionEnums;
import com.gw.vip.common.exception.ServiceException;
import com.gw.vip.server.bo.RefundRsp;
import com.gw.vip.server.enums.TxnTypeEnums;
import com.gw.vip.server.dto.AdminRefundDto;
import com.gw.vip.server.dto.TransDto;
import com.gw.vip.server.enums.CapitalEnums;
import com.gw.vip.server.po.*;
import com.gw.vip.server.service.dao_service.*;
import com.gw.vip.server.vo.AdminRefundVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * @author GW
 * @description
 * @since 2022-07-03
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class AdminTransService {

    private final ViewTransService viewTransService;
    private final UserInfoService userInfoService;
    private final OrderAllService orderAllService;
    private final BsOrderService bsOrderService;
    private final AccountBiz accountBiz;
    private final AccountService accountService;

    public IPage<ViewTrans> trans(TransDto dto) {
        //userId为空，并且nickName不为空，按照nickName查找
        String userId = dto.getUserId();
        if (StringUtils.isBlank(userId)&&StringUtils.isNotBlank(dto.getNickName())){
            UserInfo userInfo = userInfoService.getByNickName(dto.getNickName());
            if (userInfo==null){
                throw new ServiceException(ExceptionEnums.ITEM_NOT_EXIST, "用户不存在！");
            }
            userId = userInfo.getId();
        }

        return viewTransService.trans(dto.getTransId(), userId, dto.getTxnType(), dto.getCurrent(), dto.getSize());
    }

    /**
     * 网页退款
     * @param dto
     * @return
     */
    public AdminRefundVo adminRefund(AdminRefundDto dto) {
        BsOrder srcBsOrder = orderAllService.getById(dto.getSrcTransId());
        if (srcBsOrder ==null){
            log.error("原交易订单不存在！系统单号【{}】", dto.getSrcTransId());
            throw new ServiceException(ExceptionEnums.ERROR_PARAMS, "原交易订单不存在!");
        }

        if (!srcBsOrder.getOrderType().equals(TxnTypeEnums.SALE.getKey())){
            log.error("原订单【{}】不是消费订单！", srcBsOrder.getId());
            throw new ServiceException(ExceptionEnums.ERROR_PARAMS, "原订单不是消费订单");
        }

        UserInfo userinfo = userInfoService.getById(srcBsOrder.getUserId());
        if (userinfo == null) {
            log.error("用户【{}】不存在！", srcBsOrder.getUserId());
            throw new ServiceException(ExceptionEnums.ERROR_PARAMS, "用户不存在！");
        }

        BsOrder bsOrder = bsOrderService.initTransFromAdminRefund(srcBsOrder);
        if (!bsOrderService.save(bsOrder)){
            log.error("保存退款订单失败！");
            throw new ServiceException("保存退款订单失败！");
        }

        LocalDateTime txnDateTime = bsOrder.getCrtTime();
        RefundRsp refundRsp = accountBiz.refund(userinfo.getId(), bsOrder.getId(), srcBsOrder.getTxnAmt(), txnDateTime, srcBsOrder.getId());

        BigDecimal payAmt = refundRsp.getTransList().stream().filter(transAcc -> transAcc.getCapitalId().equals(CapitalEnums.CASH.getKey())).map(Trans::getTxnAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal rebateAmt = refundRsp.getTransList().stream().filter(accountTrans -> accountTrans.getCapitalId().equals(CapitalEnums.REBATE.getKey())).map(Trans::getTxnAmt).reduce(BigDecimal.ZERO, BigDecimal::add);

        //获取余额
        BigDecimal balAmt = accountService.getAvaBal(userinfo.getId());

        //更新原交易
        srcBsOrder.setRefundAmt(srcBsOrder.getTxnAmt());
        if (!orderAllService.updateById(srcBsOrder)){
            log.error("更新交易订单失败！");
            throw new ServiceException("更新交易订单失败！");
        }

        //更新trans信息
        bsOrder.setPayAmt(payAmt);
        bsOrder.setRebateAmt(rebateAmt);
        bsOrder.setBalAmt(balAmt);
        bsOrder.setStatus(StatusEnums.SUCCESS.getCode());
        if (!bsOrderService.updateById(bsOrder)){
            log.error("更新交易订单失败！");
            throw new ServiceException("更新交易订单失败！");
        }

        AdminRefundVo vo = new AdminRefundVo();
        vo.setTransId(bsOrder.getId());
        vo.setBalAmt(bsOrder.getBalAmt());
        return vo;
    }
}
